package org.planx.xmlstore.routing;

import java.io.*;
import java.net.*;

public class KademliaPerformanceTest2 {
    private static final int PORT = 7855;
    private static final int REPEAT = 1000;

    private static Kademlia kademlia = null;
    private static String name = "unknown";
    private static Identifier[] ids;
    private static PrintWriter out = null;
    private static Configuration conf;

    public static void main(String args[]) {
        try {
            if (args.length < 3) {
                System.out.println("Usage: KademliaPerformanceTest "+
                                   "B K CONCURRENCY [bootstrap]");
                return;
            }
            conf = new Configuration();
            conf.B = Integer.parseInt(args[0]);
            conf.K = Integer.parseInt(args[1]);
            conf.CONCURRENCY = Integer.parseInt(args[2]);

            InetSocketAddress bootstrap = null;
            if ((args.length > 3) && (args[3].length() > 0)) {
                bootstrap = new InetSocketAddress(InetAddress.getByName(args[3]), PORT);
            }
            name = InetAddress.getLocalHost().getHostName();


            kademlia = new Kademlia(Identifier.randomIdentifier(), PORT, conf);
            if (bootstrap != null) {
                kademlia.connect(bootstrap);
            }

            Object dummy = new Object();

            ids = new Identifier[REPEAT];
//            out = new PrintWriter(new BufferedWriter(new FileWriter(args[5], true)));
//            out.print(conf.B+" "+conf.K+" "+conf.CONCURRENCY+" ");

            System.gc();
            synchronized (dummy) {dummy.wait(10000);}
            for (int i=0; i<20; i++) {
                testWriteThroughput();
            }

//            System.gc();
//            synchronized (dummy) {dummy.wait(2000);}
//            testReadThroughput();

//            out.println();
//            out.close();
            System.out.println(kademlia);

        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
//            System.out.println(name+" stopping");
            try {
                if (kademlia != null) kademlia.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    public static void testWriteThroughput() throws Exception {
        Serializable dummy = Boolean.TRUE;
        long before = System.currentTimeMillis();

        for (int i=0; i<REPEAT; i++) {
            Identifier key = Identifier.randomIdentifier();
            ids[i] = key;
            kademlia.put(key, dummy);
        }

        long after = System.currentTimeMillis();
        double time = (after - before) / 1000D;
        System.out.println(name+", mappings per second: "+REPEAT/time);
//        out.print(REPEAT/time);
//        out.print(" ");
    }

    public static void testReadThroughput() throws Exception {
        long before = System.currentTimeMillis();

        for (int i=0; i<REPEAT; i++) {
            kademlia.get(ids[i]);
        }

        long after = System.currentTimeMillis();
        double time = (after - before) / 1000D;
        System.out.println(""+REPEAT+" mappings looked up in "+time+" seconds");
        System.out.println("Mappings per second, total:    "+REPEAT/time);
        int ext = (int) (REPEAT - kademlia.internalGetMap().rnum());
        System.out.println("Mappings per second, external: "+ext/time);
        System.out.println();
        out.print(REPEAT/time);
        out.print(" ");
        out.print(ext/time);
        out.print(" ");
    }
}
